package com.heima.datasync.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.constants.datasync.DataSyncIndexConstants;
import com.heima.common.exception.CustException;
import com.heima.datasync.mapper.ApArticleMapper;
import com.heima.datasync.service.EsDataService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.vos.SearchArticleVo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class EsDataServiceImpl implements EsDataService {
    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Autowired
    ApArticleMapper apArticleMapper;

    /**
     * 将文章数据库的数据导入es索引库
     *
     * @return
     */
    @Override
    public ResponseResult dataInit() {
        /*//判断索引库是否存在
        GetIndexRequest getIndexRequest = new GetIndexRequest(DataSyncIndexConstants.ARTICLE_INDEX_NAME);
        boolean flag = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        if (flag) {//存在则删除索引库
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(DataSyncIndexConstants.ARTICLE_INDEX_NAME);
            DeleteResponse deleteResponse = restHighLevelClient.delete(deleteIndexRequest, RequestOptions.DEFAULT);
            System.out.println(deleteResponse.status().getStatus());
        }
        //创建索引库
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(DataSyncIndexConstants.ARTICLE_INDEX_NAME);
        //设置索引库
        createIndexRequest.settings("{\n" +
                "    \"number_of_shards\": 1,\n" +
                "    \"number_of_replicas\": 1\n" +
                "  }", XContentType.JSON);
        //设置索引库映射
        createIndexRequest.mapping("{\n" +
                "        \"properties\":{\n" +
                "            \"id\":{\n" +
                "                \"type\":\"long\"\n" +
                "            },\n" +
                "            \"publishTime\":{\n" +
                "                \"type\":\"date\"\n" +
                "            },\n" +
                "            \"layout\":{\n" +
                "                \"type\":\"integer\"\n" +
                "            },\n" +
                "            \"images\":{\n" +
                "                \"type\":\"keyword\"\n" +
                "            },\n" +
                "            \"authorId\": {\n" +
                "          \t\t\"type\": \"long\"\n" +
                "       \t\t},\n" +
                "          \"title\":{\n" +
                "            \"type\":\"text\",\n" +
                "            \"analyzer\":\"ik_smart\"\n" +
                "          }\n" +
                "        }\n" +
                "    }", XContentType.JSON);
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices()
                .create(createIndexRequest, RequestOptions.DEFAULT);*/
        //创建索引库是否成功
//        System.out.println(createIndexResponse.isAcknowledged());
        //查询文章数据库文章内容
        List<ApArticle> articleList = apArticleMapper.findAllArticles();
        if(articleList==null||articleList.size()==0){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"查询文章数据库数据不存在");
        }
        /**
         * 模拟大数据量插入
         */
        //创建一个小容量集合
        ArrayList<SearchArticleVo> smallArticleList = new ArrayList<>();
        //设定容量为10
        int size=10;
        articleList.stream().forEach(apArticle -> {
            //创建封装es数据对象
            SearchArticleVo searchArticleVo = new SearchArticleVo();
            BeanUtils.copyProperties(apArticle,searchArticleVo);

            if(smallArticleList.size()<size&&apArticle!=articleList.get(articleList.size()-1)){
                //未达到最大容量，则将数据继续存入到当前集合中
                smallArticleList.add(searchArticleVo);
            }else {//当容量达到峰值时，则调用es批处理方法插入
                if(apArticle==articleList.get(articleList.size()-1)){
                    smallArticleList.add(searchArticleVo);
                }
                //创建批量插入请求对象
                BulkRequest bulkRequest = new BulkRequest(DataSyncIndexConstants.ARTICLE_INDEX_NAME);
                //遍历需要插入es的集合
                for (SearchArticleVo articleVo : smallArticleList) {
                    //设置文章文档
                    IndexRequest indexRequest = new IndexRequest();
                    indexRequest.id(articleVo.getId().toString())
                            .source(JSON.toJSONString(articleVo),XContentType.JSON);
                    bulkRequest.add(indexRequest);
                }
                //批处理插入数据
                try {
                    BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
                    //返回批处理结果
                    System.out.println(bulkResponse.status());
                } catch (IOException e) {
                    e.printStackTrace();
                    CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"文章批处理插入es失败");
                }
                //清空集合
                smallArticleList.clear();
            }
        });
        return ResponseResult.okResult();
    }
}
